import tkinter as tk
import pyautogui
import easyocr
import pytesseract
import time
import hashlib
import uuid
import requests
import os
from bs4 import BeautifulSoup
import numpy as np
# 设置 Tesseract OCR 的路径，根据实际安装路径修改
pytesseract.pytesseract.tesseract_cmd = r'C:\Program Files\Tesseract-OCR\tesseract.exe'
desktop_path = os.path.join(os.path.expanduser("~"), "Desktop")
file_path = os.path.join(desktop_path, 'translation_history.txt')
YOUDAO_URL = 'https://openapi.youdao.com/api'
APP_KEY = '3ec26aae9321262d'
APP_SECRET = 'xM5B9iKt3CXtAFsYv2rGUhvJptIrFLIj'


def encrypt(signStr):
    hash_algorithm = hashlib.sha256()
    hash_algorithm.update(signStr.encode('utf-8'))
    return hash_algorithm.hexdigest()


def truncate(q):
    if q is None:
        return None
    size = len(q)
    return q if size <= 20 else q[0:10] + str(size) + q[size - 10:size]


def do_request(data):
    headers = {'Content-Type': 'application/x-www-form-urlencoded'}
    response = requests.post(YOUDAO_URL, data=data, headers=headers)
    response.raise_for_status()  # 检查请求是否成功
    return response


# 参数分别为 需要翻译的语句 源语言id 目标语言id
# 返回值为翻译结果和音标
def translate(text, from_lang, to_lang):
    data = {
        'from': from_lang,
        'to': to_lang,
        'signType': 'v3',
        'curtime': str(int(time.time())),
        'appKey': APP_KEY,
        'q': text,
        'salt': str(uuid.uuid1()),
        'vocabId': ''  # 可选，用户词表ID
    }
    signStr = APP_KEY + truncate(text) + data['salt'] + data['curtime'] + APP_SECRET
    data['sign'] = encrypt(signStr)

    response = do_request(data)
    result = response.json()

    if result.get('errorCode') == '0':
        translation = result.get('translation')

        webdict_url = result.get('webdict', {}).get('url')
        if webdict_url:
            try:
                page_response = requests.get(webdict_url)
                page_response.raise_for_status()
                soup = BeautifulSoup(page_response.text, 'html.parser')

                # 提取单词
                word = soup.find('div', class_='ec').find('h2').find('span').text.strip()

                # 提取音标
                phonetic_spans = soup.find_all('span', class_='phonetic')
                phonetic = ', '.join([span.text.strip() for span in phonetic_spans])

                # 提取词性和翻译内容
                pos_translation_li = soup.find('div', class_='ec').find('ul').find_all('li')
                pos_translation = []
                for li in pos_translation_li:
                    pos_translation.append(li.text.strip())
                pos_translation_str = '\n'.join(pos_translation)


                return word, phonetic, pos_translation_str
            except Exception as e:
                print(f"抓取网页内容时出错: {e}")
                return text, "no phonetic", translation
        raise Exception("未找到 webdict URL 或抓取网页内容失败")
    else:
        raise Exception(f"Error: {result.get('errorCode')}, {result.get('errorMsg')}")


class SelectionWindow:
    def __init__(self, root):
        self.root = root
        self.start_x = None
        self.start_y = None
        self.end_x = None
        self.end_y = None

        # 创建透明顶层窗口
        self.selection_window = tk.Toplevel(root)
        self.selection_window.attributes('-fullscreen', True)
        self.selection_window.attributes('-alpha', 0.2)
        self.selection_window.overrideredirect(True)

        # 绑定鼠标事件
        self.selection_window.bind("<ButtonPress-1>", self.on_press)
        self.selection_window.bind("<B1-Motion>", self.on_drag)
        self.selection_window.bind("<ButtonRelease-1>", self.on_release)

        # 创建矩形框用于显示选择区域
        self.canvas = tk.Canvas(self.selection_window, highlightthickness=0)
        self.canvas.pack(fill=tk.BOTH, expand=True)
        self.rect = None

    def on_press(self, event):
        self.start_x = event.x
        self.start_y = event.y
        if self.rect:
            self.canvas.delete(self.rect)

    def on_drag(self, event):
        if self.start_x is not None and self.start_y is not None:
            if self.rect:
                self.canvas.delete(self.rect)
            self.end_x = event.x
            self.end_y = event.y
            self.rect = self.canvas.create_rectangle(
                self.start_x, self.start_y, self.end_x, self.end_y,
                outline='red', width=2
            )

    def on_release(self, event):
        if self.start_x is not None and self.start_y is not None:
            self.end_x = event.x
            self.end_y = event.y
            self.selection_window.destroy()

    def get_selection_coords(self):
        left = min(self.start_x, self.end_x)
        top = min(self.start_y, self.end_y)
        width = abs(self.end_x - self.start_x)
        height = abs(self.end_y - self.start_y)
        return left, top, width, height



def get_selection():
    root = tk.Tk()
    root.withdraw()
    selection = SelectionWindow(root)
    root.wait_window(selection.selection_window)
    left, top, width, height = selection.get_selection_coords()
    # 截取屏幕指定部分
    screenshot = pyautogui.screenshot(region=(left, top, width, height))
    # 将 PIL 图像转换为 numpy 数组
    screenshot_np = np.array(screenshot)

    # 使用 easyOCR 进行 OCR 识别
    # 创建 OCR 阅读器，指定语言为英文
    reader = easyocr.Reader(['en'])

    # 读取图像数据
    text = reader.readtext(screenshot_np)
    #print(text)
    # 输出识别结果
    full_text = ""
    for detection in text:
        # detection 是一个元组，detection[1] 是识别出的文本字符串
        print(detection[1])
        full_text += detection[1] + " "
    try:
        text, phonetic, translation = translate(full_text, 'en', 'zh-CHS')
        show_translation_in_main(text, translation, phonetic)
        save_to_file(text, translation, phonetic)
    except Exception as e:
        error_label.config(text=f"翻译过程中出现错误: {e}")


def show_translation_in_main(original_text, translation, phonetic):
    original_text_widget.delete(1.0, tk.END)
    original_text_widget.insert(tk.END, f"原文: {original_text}")

    phonetic_text_widget.delete(1.0, tk.END)
    phonetic_text_widget.insert(tk.END, f"音标: {phonetic}")

    translation_text_widget.delete(1.0, tk.END)
    translation_text_widget.insert(tk.END, f"翻译: {translation}")


def save_to_file(original_text, translation, phonetic):
    try:
        with open(file_path, 'a', encoding='utf-8') as f:
            f.write(f"原文: {original_text}\n")
            f.write(f"音标: {phonetic}\n")
            f.write(f"翻译: {translation}\n")
            f.write("-" * 50 + "\n")
        save_info_label.config(text="翻译结果已保存到 translation_history.txt 文件中。")
    except Exception as e:
        save_info_label.config(text=f"保存文件时出现错误: {e}")


# 创建主窗口
main_root = tk.Tk()
main_root.title("英文框选翻译软件")
main_root.geometry("400x500")  # 设置窗口初始大小
main_root.configure(bg="#f0f0f0")  # 设置窗口背景颜色

# 设置字体样式
font_style = ("Arial", 12)

# 创建开始按钮
start_button = tk.Button(main_root, text="开始框选翻译", command=get_selection, font=font_style)
start_button.pack(pady=20)

# 创建用于显示原文、音标、翻译结果的文本框及滚动条
original_frame = tk.Frame(main_root)
original_frame.pack(pady=5)
original_scrollbar = tk.Scrollbar(original_frame)
original_scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
original_text_widget = tk.Text(original_frame, wrap=tk.WORD, yscrollcommand=original_scrollbar.set, height=5, font=font_style, bg="#f0f0f0")
original_text_widget.pack()
original_scrollbar.config(command=original_text_widget.yview)

phonetic_frame = tk.Frame(main_root)
phonetic_frame.pack(pady=5)
phonetic_scrollbar = tk.Scrollbar(phonetic_frame)
phonetic_scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
phonetic_text_widget = tk.Text(phonetic_frame, wrap=tk.WORD, yscrollcommand=phonetic_scrollbar.set, height=3, font=font_style, bg="#f0f0f0")
phonetic_text_widget.pack()
phonetic_scrollbar.config(command=phonetic_text_widget.yview)

translation_frame = tk.Frame(main_root)
translation_frame.pack(pady=5)
translation_scrollbar = tk.Scrollbar(translation_frame)
translation_scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
translation_text_widget = tk.Text(translation_frame, wrap=tk.WORD, yscrollcommand=translation_scrollbar.set, height=5, font=font_style, bg="#f0f0f0")
translation_text_widget.pack()
translation_scrollbar.config(command=translation_text_widget.yview)

# 创建用于显示保存信息和错误信息的标签
save_info_label = tk.Label(main_root, text="", font=font_style, bg="#f0f0f0")
save_info_label.pack(pady=5)

error_label = tk.Label(main_root, text="", font=font_style, bg="#f0f0f0", fg="red")
error_label.pack(pady=5)

# 运行主循环
main_root.mainloop()